//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// Contact: mcseem@antigrain.com
//          mcseemagg@yahoo.com
//          http://antigrain.com
// 
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
// 
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
// MA 02110-1301, USA.
//----------------------------------------------------------------------------

#ifndef AGG_FONT_FREETYPE_INCLUDED
#define AGG_FONT_FREETYPE_INCLUDED

#include <ft2build.h>
#include FT_FREETYPE_H


#include "agg_scanline_storage_aa.h"
#include "agg_scanline_storage_bin.h"
#include "agg_scanline_u.h"
#include "agg_scanline_bin.h"
#include "agg_path_storage_integer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_conv_curve.h"
#include "agg_trans_affine.h"

#include "font.h"
#include "fontcache.h"


namespace agg
{

    //-----------------------------------------------font_engine_freetype_base
    class font_engine_freetype_base
    {
    public:
        //--------------------------------------------------------------------
        typedef serialized_scanlines_adaptor_aa<int8u>    gray8_adaptor_type;
        typedef serialized_scanlines_adaptor_bin          mono_adaptor_type;
        typedef scanline_storage_aa8                      scanlines_aa_type;
        typedef scanline_storage_bin                      scanlines_bin_type;

        //--------------------------------------------------------------------
        ~font_engine_freetype_base();
        font_engine_freetype_base(bool flag32);

        // Set font parameters
        //--------------------------------------------------------------------
        // needed
        void resolution(unsigned dpi);
        // needed
		void* load_font(void* face, glyph_rendering ren_type);
        void* load_font(const char* file_name, unsigned face_index, glyph_rendering ren_type);

        bool get_font_info(const char* file_name, int faceid,
            visgrph::fontstyle& style, char family_name[64]);
       
        // needed
        bool char_map(FT_Encoding map);

        // needed
        bool height(double h);
        // needed
        bool width(double w);

        // needed
        void hinting(bool h) { m_hinting = h; }
        // needed
        void flip_y(bool f) { m_flip_y = f; }
        // needed
        void transform(const trans_affine& affine) { m_affine = affine; }

        // needed
        // Set Gamma
        //--------------------------------------------------------------------
        template<class GammaF> void gamma(const GammaF& f)
        {
            m_rasterizer.gamma(f);
        }

        // Accessors
        //--------------------------------------------------------------------
        // needed
        int         last_error()   const { return m_last_error; }
        // needed
        unsigned    resolution()   const { return m_resolution; }
        unsigned    num_faces()    const;
        // needed
        FT_Encoding char_map()     const { return m_char_map;   }
        // needed
        double      height()       const { return double(m_height) / 64.0;    }
        // needed
        double      width()        const { return double(m_width) / 64.0;     }
        double      ascender()     const;
        double      descender()    const;
        bool        hinting()      const { return m_hinting;    }
        bool        flip_y()       const { return m_flip_y;     }


        // Interface mandatory to implement for font_cache_manager
        //--------------------------------------------------------------------
        unsigned int	prepare_glyph(unsigned glyph_code);

        unsigned        data_size()   const { return m_data_size;   }
        glyph_data_type data_type()   const { return m_data_type;   }
        const rect_i&   bounds()      const { return m_bounds;      }
        double          advance_x()   const { return m_advance_x;   }
        double          advance_y()   const { return m_advance_y;   }
        void            write_glyph_to(int8u* data) const;
        bool            add_kerning(unsigned first, unsigned second,
                                    double* x, double* y);


        // needed:
		//--------------------------------------------------------------------
		unsigned path32_size() const { return m_path32.size(); }
		void path32_rewind(void) { m_path32.rewind(0);}
		unsigned path32_vertex(double* x, double* y) { return m_path32.vertex(x, y); }

    private:
        font_engine_freetype_base(const font_engine_freetype_base&);
        const font_engine_freetype_base& operator = (const font_engine_freetype_base&);

        // needed
        void update_char_size();
		void set_ren_type(glyph_rendering ren_type);

        bool               m_flag32;                    // needed: for path16 or path32
        int                m_last_error;                // needed: last error of freetype
        unsigned           m_face_index;
        FT_Encoding        m_char_map;                  // needed:
        unsigned           m_height;                    // needed: current height
        unsigned           m_width;                     // needed: current width
        bool               m_hinting;                   // needed:
        bool               m_flip_y;                    // needed:
        FT_Library         m_library;                   // needed: handle to library    
        FT_Face            m_cur_face;                  // needed: handle to the current face object
        int                m_resolution;                // needed:
        glyph_rendering    m_glyph_rendering;
        unsigned           m_data_size;
        glyph_data_type    m_data_type;
        rect_i             m_bounds;
        double             m_advance_x;
        double             m_advance_y;
        trans_affine       m_affine;

        path_storage_integer<int16, 6>              m_path16;
        path_storage_integer<int32, 6>              m_path32;
        conv_curve<path_storage_integer<int16, 6> > m_curves16;
        conv_curve<path_storage_integer<int32, 6> > m_curves32;
        scanline_u8              m_scanline_aa;
        scanline_bin             m_scanline_bin;
        scanlines_aa_type        m_scanlines_aa;
        scanlines_bin_type       m_scanlines_bin;
        rasterizer_scanline_aa<> m_rasterizer;
    };




    //------------------------------------------------font_engine_freetype_int16
    // This class uses values of type int16 (10.6 format) for the vector cache. 
    // The vector cache is compact, but when rendering glyphs of height
    // more that 200 there integer overflow can occur.
    //
    class font_engine_freetype_int16 : public font_engine_freetype_base
    {
    public:
        typedef serialized_integer_path_adaptor<int16, 6>     path_adaptor_type;
        typedef font_engine_freetype_base::gray8_adaptor_type gray8_adaptor_type;
        typedef font_engine_freetype_base::mono_adaptor_type  mono_adaptor_type;
        typedef font_engine_freetype_base::scanlines_aa_type  scanlines_aa_type;
        typedef font_engine_freetype_base::scanlines_bin_type scanlines_bin_type;

        font_engine_freetype_int16() : 
            font_engine_freetype_base(false) {}
    };

    //------------------------------------------------font_engine_freetype_int32
    // This class uses values of type int32 (26.6 format) for the vector cache. 
    // The vector cache is twice larger than in font_engine_freetype_int16, 
    // but it allows you to render glyphs of very large sizes.
    //
    class font_engine_freetype_int32 : public font_engine_freetype_base
    {
    public:
        typedef serialized_integer_path_adaptor<int32, 6>     path_adaptor_type;
        typedef font_engine_freetype_base::gray8_adaptor_type gray8_adaptor_type;
        typedef font_engine_freetype_base::mono_adaptor_type  mono_adaptor_type;
        typedef font_engine_freetype_base::scanlines_aa_type  scanlines_aa_type;
        typedef font_engine_freetype_base::scanlines_bin_type scanlines_bin_type;

        font_engine_freetype_int32() : 
            font_engine_freetype_base(true) {}
    };


}

#endif
